import { CSDashLine, CSPoint } from '@amcax/base';
import { PickInputRJSFFormat } from '@app-base/common/components/command-form/constants';
import { composeFormat } from '@app-base/common/components/command-form/utils';
import { ctx2 } from '@app-base/module';
import { RJSFSchema, UiSchema } from '@rjsf/utils';
import { Object3D, Vector3, Vector3Tuple } from 'three-legacy';

export const SetPick = (
  PickType: string | string[],
  title?: string,
): RJSFSchema => ({
  type: 'string',
  format: Array.isArray(PickType)
    ? composeFormat(PickType)
    : PickInputRJSFFormat[PickType],
  title: title || '',
});

export const Picktip = (
  focus: boolean = false,
  tip: string = '线',
  prefix: string = '请选择',
): UiSchema => ({
  'ui:placeholder': `${prefix}${tip}`,
  'ui:autofocus': focus,
});

//  -----------------------------------------------------------
type State = 'id' | 'normal' | 'all';
type RetType = {
  normal?: string[] | Vector3Tuple[];
  id?: string;
};
export function getNormalsOrIds(
  pickObjs,
  status: Array<State> | State,
): RetType[] {
  const normalIds = [];
  pickObjs?.forEach((item, ind) => {
    const state = Array.isArray(status) ? status[ind] : status;
    const temp = getNormalOrId(item, state || 'id');
    (temp.id || temp.normal) && normalIds.push(temp);
  });
  return normalIds;
}

export function getNormalOrId(pickObj, state: State = 'all'): RetType {
  let normal = null;
  let id = null;
  if (pickObj?.assisObj?.name === 'pickedObject') {
    if (state === 'id' || state === 'all') {
      id = pickObj?.objInfo?.dxid;
    }
  } else if (pickObj?.meshId) {
    if (state === 'normal' || state === 'all') {
      const ind = pickObj?.meshId.split(':')[1]?.substring(1);
      normal = pickObj?.modelData?.faces[ind || 0].normals?.[0];
    } else if (state === 'id' || state === 'all') {
      id = pickObj?.meshId;
    }
  } else if (pickObj?.edgeData?.length >= 2) {
    if (state === 'normal' || state === 'all') {
      const [v1, v2] = pickObj.edgeData;
      const vector = new Vector3().subVectors(v2, v1).normalize();
      normal = vector.toArray();
    } else if (state === 'id' || state === 'all') {
      id = pickObj?.edgeId;
    }
  } else if (pickObj?.vertexId && (state === 'id' || state === 'all')) {
    id = pickObj?.vertexId;
  }
  return { normal, id };
}

let assistPoint: CSPoint = null;
export const createPoint = (vertexs: Vector3[] | Vector3Tuple[]) => {
  if (vertexs.length <= 0) {
    return;
  }
  assistPoint = new CSPoint({
    pointType: 'vertex',
    size: 10,
  });
  assistPoint.hoverOn();
  assistPoint.setVertexs(vertexs);
  assistPoint.addTo(ctx2.cadScene.toolsGroup);
};

export const removePoint = () => {
  ctx2.cadScene.toolsGroup.remove(assistPoint);
  assistPoint?.destroy();
  assistPoint = null;
};
type Setting = {
  dashSize?: number;
  gapSize?: number;
  dashed?: boolean;
  lineWidth?: number;
  color?: string;
};
const preLineParam: Setting = {
  dashSize: 10,
  gapSize: 5,
  dashed: true,
  lineWidth: 2, // 线条宽度
};
// 创建线
export const createUpdateLine = (
  vertexs: Vector3[],
  line,
  assisGroup?: Object3D,
  setting?: Setting,
) => {
  if (vertexs?.length < 2) {
    return;
  }
  if (line) {
    line.update({
      vertexs: vertexs,
      dashed: false,
    });
  } else {
    let param = {
      vertexs: vertexs,
      lineWidth: 3,
      dashed: false,
      depthTest: false, // 不进行深度测试
    };
    param = Object.assign(param, preLineParam, setting);
    line = new CSDashLine({
      ...param,
    });
    line.addTo(assisGroup);
  }
  return line;
};
